#pragma once
#include <functional>
#include <string>
#include <pthread.h>
#include <atomic>
#include <thread>
#include <memory>

#include "noncopyable.h"

class Thread : noncopyable
{
public:
    using ThreadFunc = std::function<void()>;
    explicit Thread(ThreadFunc func, const std::string &name = std::string());

    ~Thread();

    void start();

    void join();

    bool started() const { return started_; }

    pid_t tid() const { return tid_; }
    const std::string &name() const { return name_; }

private:
    void setDefaultName();

    std::shared_ptr<std::thread> thread_;
    bool started_;
    bool joined_;
    pthread_t pthreadId_;
    pid_t tid_;
    ThreadFunc func_;
    std::string name_;

    static std::atomic<int32_t> numCreated_;
};